package com.wing.cabinet.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.cabinet.dao.CheckedInventoryInoutDetailDao;
import com.wing.cabinet.model.entity.*;
import com.wing.cabinet.model.request.CellInventoryInoutDetailForm;
import com.wing.cabinet.model.request.CheckedInventoryInoutDetailForm;
import com.wing.cabinet.model.request.StorageInventoryInoutDetailForm;
import com.wing.cabinet.model.request.UseInventoryInoutDetailForm;
import com.wing.cabinet.model.response.CabinetCargoSpaceVO;
import com.wing.cabinet.model.response.CheckedInventoryInoutDetailVO;
import com.wing.common.exception.BusinessException;
import com.wing.config.BaseDataInit;
import com.wing.order.service.DynamicService;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 暂存柜存刀/取刀;存/取维修/回收刀盘验明细-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class CheckedInventoryInoutDetailServiceImpl extends ServiceImpl<CheckedInventoryInoutDetailDao, CheckedInventoryInoutDetail> implements CheckedInventoryInoutDetailService {

    @Autowired
    private DynamicService dynamicService;

    @Autowired
    private CheckedInventoryInoutService inventoryInoutService;

    @Autowired
    private CheckedInventoryProductService inventoryProductService;

    @Autowired
    private UseInventoryUserKnifeService useInventoryUserKnifeService;

    @Override
    public int add(CheckedInventoryInoutDetailForm checkedInventoryInoutDetailForm) {

        //校验

        CheckedInventoryInoutDetail checkedInventoryInoutDetail =new CheckedInventoryInoutDetail();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(CheckedInventoryInoutDetail.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(checkedInventoryInoutDetailForm, checkedInventoryInoutDetail, copyOptions);

        return baseMapper.insert(checkedInventoryInoutDetail);
    }

    @Override
    public List<CheckedInventoryInoutDetailVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<CheckedInventoryInoutDetailVO> pageList4app(Page page, Map<String, Object> params) {
        List<CheckedInventoryInoutDetailVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public CheckedInventoryInoutDetailVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }


    @Override
    @Transactional
    public CheckedInventoryInout inventoryIn(List<StorageInventoryInoutDetailForm> list, Long storageInoutId, CheckedInventoryInout.BusinessType businessType,CheckedInventoryInout.BusinessTypePre businessTypePre) {
        Long enterpriseId=JwtUtils.getEnterpriseId();
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        String departmentName=JwtUtils.getDepartmentName();
        Long departmentId=JwtUtils.getDepartmentId();
        String roleName=JwtUtils.getRoleName();
        Long roleId=JwtUtils.getRoleId();
        String channelCode=JwtUtils.getChannelCode();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        CheckedInventoryInout checkedInventoryInout=new CheckedInventoryInout();
        String code=dynamicService.getDayNextCode("cab_checked_inventory_inout");
        String day=simpleDateFormat.format(new Date());
        checkedInventoryInout.setCode("IN-"+day+"-"+code);
        checkedInventoryInout.setDay(Integer.valueOf(day));
        checkedInventoryInout.setNo(Integer.valueOf(code));
        checkedInventoryInout.setCreator(JwtUtils.getLoginUserId());
        checkedInventoryInout.setCreatorName(JwtUtils.getLoginUsername());
        checkedInventoryInout.setOperationType(CheckedInventoryInout.OperationType.in);
        checkedInventoryInout.setBusinessType(businessType);
        checkedInventoryInout.setStorageInoutId(storageInoutId);
        checkedInventoryInout.setCompanyId(enterpriseId);
        checkedInventoryInout.setBusinessTypePre(businessTypePre);
        checkedInventoryInout.setRemark(businessTypePre.getDesc()+"->"+businessType.getDesc());
        checkedInventoryInout.setEnterpriseCode(enterpriseCode);
        checkedInventoryInout.setChannelCode(channelCode);
        checkedInventoryInout.setDepartmentId(departmentId);
        checkedInventoryInout.setDepartmentName(departmentName);
        checkedInventoryInout.setRoleId(roleId);
        checkedInventoryInout.setRoleName(roleName);
        inventoryInoutService.save(checkedInventoryInout);
        List<CheckedInventoryInoutDetailForm> listIn=new ArrayList<>();
        for (StorageInventoryInoutDetailForm detailForm:list){
            CheckedInventoryInoutDetailForm cellInventoryInoutDetailForm=new CheckedInventoryInoutDetailForm();
            BeanUtils.copyProperties(detailForm,cellInventoryInoutDetailForm);
            listIn.add(cellInventoryInoutDetailForm);
        }
        saveDetail(listIn,checkedInventoryInout.getId(),UseInventoryInout.Type.in.name(),businessType);
        return checkedInventoryInout;
    }

    @Override
    @Transactional
    public void inventoryOut(List<CheckedInventoryInoutDetailForm> list, CheckedInventoryInout.BusinessType businessType) {
        String departmentName=JwtUtils.getDepartmentName();
        Long departmentId=JwtUtils.getDepartmentId();
        String roleName=JwtUtils.getRoleName();
        Long roleId=JwtUtils.getRoleId();
        String channelCode=JwtUtils.getChannelCode();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        CheckedInventoryInout checkedInventoryInout=new CheckedInventoryInout();
        String code=dynamicService.getDayNextCode("cab_checked_inventory_inout");
        String day=simpleDateFormat.format(new Date());
        checkedInventoryInout.setCode("OU-"+day+"-"+code);
        checkedInventoryInout.setDay(Integer.valueOf(day));
        checkedInventoryInout.setNo(Integer.valueOf(code));
        checkedInventoryInout.setCreator(JwtUtils.getLoginUserId());
        checkedInventoryInout.setCreatorName(JwtUtils.getLoginUsername());
        checkedInventoryInout.setOperationType(CheckedInventoryInout.OperationType.out);
        checkedInventoryInout.setBusinessType(businessType);
        checkedInventoryInout.setEnterpriseCode(JwtUtils.getEnterpriseCode());
        checkedInventoryInout.setChannelCode(channelCode);
        checkedInventoryInout.setDepartmentId(departmentId);
        checkedInventoryInout.setDepartmentName(departmentName);
        checkedInventoryInout.setRoleId(roleId);
        checkedInventoryInout.setRoleName(roleName);
        inventoryInoutService.save(checkedInventoryInout);

        saveDetail(list,checkedInventoryInout.getId(),UseInventoryInout.Type.out.name(),businessType);
    }



    @Transactional
    void saveDetail(List<CheckedInventoryInoutDetailForm> list, Long inventoryInoutId, String inOutTypeName,CheckedInventoryInout.BusinessType businessType){
        Long enterpriseId=JwtUtils.getEnterpriseId();
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        String channelCode=JwtUtils.getChannelCode();
        if (CollectionUtils.isNotEmpty(list)){
            for (CheckedInventoryInoutDetailForm checkedInventoryInoutDetailForm:list){
                CheckedInventoryInoutDetail checkedInventoryInoutDetail=new CheckedInventoryInoutDetail();
                BeanUtils.copyProperties(checkedInventoryInoutDetailForm,checkedInventoryInoutDetail);
                checkedInventoryInoutDetail.setId(null);
                checkedInventoryInoutDetail.setCompanyId(enterpriseId);
                checkedInventoryInoutDetail.setEnterpriseCode(enterpriseCode);
                checkedInventoryInoutDetail.setCreator(creator);
                checkedInventoryInoutDetail.setCreatorName(creatorName);
                checkedInventoryInoutDetail.setOperationType(CheckedInventoryInoutDetail.OperationType.jsonCreator(inOutTypeName));
                checkedInventoryInoutDetail.setBusinessType(CheckedInventoryInoutDetail.BusinessType.jsonCreator(businessType.name()));
                checkedInventoryInoutDetail.setInoutId(inventoryInoutId);
                checkedInventoryInoutDetail.setChannelCode(channelCode);
                List<CheckedInventoryProduct> skuInventoryList=inventoryProductService.list(new QueryWrapper<CheckedInventoryProduct>().eq("sku_code",checkedInventoryInoutDetailForm.getSkuCode()).eq("business_type",businessType.getValue()).eq("enterprise_code",enterpriseCode));

                Integer quantity=checkedInventoryInoutDetailForm.getQuantity();
                if (UseInventoryInout.Type.out.name().equals(inOutTypeName)){
                    if (skuInventoryList.size()==0){
                        throw new BusinessException("未找到SKU["+checkedInventoryInoutDetailForm.getSkuCode()+"]的刀具产品");
                    }else{
                        if (quantity<=0){
                            throw new BusinessException("取数量参数异常");
                        }
                        if (quantity>0){
                            quantity=-1*quantity;
                        }

                        Integer currentQuantity=skuInventoryList.get(0).getQuantity();
                        Integer newQuantity=currentQuantity+quantity;
                        if (newQuantity<0){
//                            throw new BusinessException("SKU["+checkedInventoryInoutDetailForm.getSkuCode()+"]的刀具产品库存不足");
                        }



                        CheckedInventoryProduct checkedInventoryProduct=new CheckedInventoryProduct();
                        checkedInventoryProduct.setId(skuInventoryList.get(0).getId());
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(skuInventoryList.get(0).getQuantity()+quantity);
//                        checkedInventoryProduct.setBusinessType(CheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));

                        if (newQuantity<=0){
                            inventoryProductService.removeById(skuInventoryList.get(0).getId());
                        }else{
                            inventoryProductService.updateById(checkedInventoryProduct);
                        }


                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }
                }else if(UseInventoryInout.Type.in.name().equals(inOutTypeName)){
                    if (quantity<=0){
                        throw new BusinessException("存数量参数异常");
                    }

                    UseInventoryUserKnife useInventoryUserKnife=new UseInventoryUserKnife();
                    useInventoryUserKnife.setStatus(UseInventoryUserKnife.Status.outChecked);
                    useInventoryUserKnifeService.update(useInventoryUserKnife,new QueryWrapper<UseInventoryUserKnife>().eq("code",checkedInventoryInoutDetailForm.getLabelCode()));

                    if (skuInventoryList.size()==0){
                        Integer currentQuantity=0;
                        Integer newQuantity=currentQuantity+quantity;

                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }else{

                        Integer currentQuantity=skuInventoryList.get(0).getQuantity();
                        Integer newQuantity=currentQuantity+quantity;

                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }



                    if (skuInventoryList.size()==0){
                        CheckedInventoryProduct checkedInventoryProduct=new CheckedInventoryProduct();
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(quantity);
                        checkedInventoryProduct.setBusinessType(CheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));
                        checkedInventoryProduct.setCompanyId(enterpriseId);
                        checkedInventoryProduct.setEnterpriseCode(enterpriseCode);
                        checkedInventoryProduct.setChannelCode(channelCode);
                        inventoryProductService.save(checkedInventoryProduct);
                    }else{
                        CheckedInventoryProduct checkedInventoryProduct=new CheckedInventoryProduct();
                        checkedInventoryProduct.setId(skuInventoryList.get(0).getId());
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(skuInventoryList.get(0).getQuantity()+quantity);
                        checkedInventoryProduct.setBusinessType(CheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));
                        checkedInventoryProduct.setChannelCode(channelCode);
                        inventoryProductService.updateById(checkedInventoryProduct);
                    }
                }else{
                    throw new BusinessException("出入库类型参数异常");
                }

            }
        }else{
            throw new BusinessException("未提交存放刀具数据");
        }
    }

}
